﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace jumping_on_blocks
{
    /**
     * Camera
     * 
     * adapted from Caleb Pentecost's original
     **/
    class Camera
    {
        public Vector3 position;
        public Matrix viewMatrix, projectionMatrix, rotation;

        private float fov, aspectRatio, minDraw, maxDraw;

        private float m_leftrightRot;
        private float m_updownRot;

        public float rotationSpeed = 0.06f;
        public float moveSpeed = 0.25f;

        private Player following;

        public float leftrightRot
        {
            get { return m_leftrightRot; }
            set
            {
                m_leftrightRot = value;
                UpdateRotation();
            }
        }

        public float updownRot
        {
            get { return m_updownRot; }
            set
            {
                m_updownRot = value;
                UpdateRotation();
            }
        }

        public Camera(GraphicsDevice device)
        {
            position = new Vector3(0, 0, 0);
            aspectRatio = device.Viewport.AspectRatio;
            fov = MathHelper.ToRadians(45.0f);
            minDraw = .01f;
            maxDraw = 500f;

            updownRot = 0f;
            leftrightRot = -(float)Math.PI;

            ResetCamera();
        }

        public void ResetCamera()
        {
            position = Vector3.Zero;
            viewMatrix = Matrix.Identity;
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(fov, aspectRatio, minDraw, maxDraw);
        }

        public void Follow(Player player)
        {
            following = player;
        }

        public void setPosition(Vector3 pos)
        {
            position = pos;
        }

        public void Update()
        {
            if (following != null)
            {
                m_leftrightRot = following.leftrightRot;
                m_updownRot = following.updownRot;
                position = following.Pos;
                rotation = following.Rot;
            }
            //Whoa, dude. If you just put vector3.up for the camera upvector, things get wiggy if you look at the ground.
            viewMatrix = Matrix.CreateLookAt(position, position + Vector3.Transform(Vector3.Forward, rotation), Vector3.Transform(Vector3.Up, rotation));
        }

        public void Move(Vector3 change)
        {
            position += moveSpeed * Vector3.Transform(change, rotation);
        }

        private void UpdateRotation()
        {
            rotation = Matrix.CreateRotationX(m_updownRot) * Matrix.CreateRotationY(m_leftrightRot);
        }
    }
}
